﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using IVideo;
using System.Windows.Forms;
using IAlarm;
using IAnalyze;
using System.Diagnostics;
using AlarmManager;
using VideoFile;
using System.IO;
using VirtualControl;
using Player;

namespace Video
{
    /*
     *  视频控件最新设计方案：
     *      1、发生报警时直接在视频上标注，在当前报警组结束之前可以对其进行处理。
     *      2、可直接从视频画面切换至历史报警画面和历史录像画面。
     *      3、历史报警与历史录像溶合，当回放录像时如存在报警则在录像中标注。
     *      4、历史报警与录像共用时间轴。
     *  该设计将视频、报警、录像集成到一个控件上，可以快速的实现它们之间的切换和关联
     */
    /// <summary>
    /// 用户视频控件
    /// </summary>
    public class UserVideo : VideoBase
    {
        UserPlayer userPlayer;

        #region 构造函数
        public UserVideo()
            : base()
        {
            InitializeVirtualControl();
        }

        protected override void OnInitialized()
        {
            base.OnInitialized();

            if (this.IsInitialized)
            {
                if (!videos.ContainsKey(this.areaName)) videos.Add(this.areaName, new Dictionary<string, UserVideo>());
                videos[this.areaName].Add(this.deviceName, this);
                this.userPlayer = new UserPlayer(this.areaName, this.deviceName);
                this.userPlayer.Visible = false;
                this.userPlayer.Dock = DockStyle.Fill;
            }
        }
        #endregion

        #region 虚拟界面
        void InitializeVirtualControl()
        {
            VBVideoCruise = new VirtualButton(this);
            VBVideoCruise.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            VBVideoCruise.Bounds = new Rectangle(this.Width - 100 - 1, 1, 18, 18);
            VBVideoCruise.Text = "巡";
            VBVideoCruise.CheckedEnabled = true;
            VBVideoCruise.CheckedBinding = GetCruiseChecked;
            VBVideoCruise.ParentMinSize = new Size(176, 0);
            VBVideoCruise.ParentMouseLeaveHide = true;
            VBVideoCruise.ParentMouseLeaveCheckedShow = true;
            VBVideoCruise.MouseClick += new EventHandler<MouseEventArgs>(VBVideoCruise_MouseClick);

            VBVideoAnalyze = new VirtualButton(this);
            VBVideoAnalyze.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            VBVideoAnalyze.Bounds = new Rectangle(this.Width - 80 - 1, 1, 18, 18);
            VBVideoAnalyze.Text = "识";
            VBVideoAnalyze.CheckedEnabled = true;
            VBVideoAnalyze.CheckedBinding = GetAnalyzeChecked;
            VBVideoAnalyze.ParentMinSize = new Size(156, 0);
            VBVideoAnalyze.ParentMouseLeaveHide = true;
            VBVideoAnalyze.ParentMouseLeaveCheckedShow = true;
            VBVideoAnalyze.MouseClick += new EventHandler<MouseEventArgs>(VBVideoAnalyze_MouseClick);

            VBVideoRecord = new VirtualButton(this);
            VBVideoRecord.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            VBVideoRecord.Bounds = new Rectangle(this.Width - 60 - 1, 1, 18, 18);
            VBVideoRecord.Text = "录";
            VBVideoRecord.CheckedEnabled = true;
            VBVideoRecord.CheckedBinding = GetRecordChecked;
            VBVideoRecord.ParentMinSize = new Size(136, 0);
            VBVideoRecord.ParentMouseLeaveHide = true;
            VBVideoRecord.ParentMouseLeaveCheckedShow = true;
            VBVideoRecord.MouseClick += new EventHandler<MouseEventArgs>(VBVideoRecord_MouseClick);

            VBVideoSnap = new VirtualButton(this);
            VBVideoSnap.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            VBVideoSnap.Bounds = new Rectangle(this.Width - 40 - 1, 1, 18, 18);
            VBVideoSnap.Text = "拍";
            VBVideoSnap.ParentMinSize = new Size(116, 0);
            VBVideoSnap.ParentMouseLeaveHide = true;
            VBVideoSnap.ParentMouseLeaveCheckedShow = true;
            VBVideoSnap.MouseClick += new EventHandler<MouseEventArgs>(VBVideoSnap_MouseClick);

            VBClose = new VirtualButton(this);
            VBClose.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            VBClose.Bounds = new Rectangle(this.Width - 20 - 1, 1, 18, 18);
            VBClose.Text = "关";
            VBClose.ParentMouseLeaveHide = true;
            VBClose.ParentMouseLeaveCheckedShow = true;
            VBClose.MouseClick += new EventHandler<MouseEventArgs>(VBClose_MouseClick);

            VBTiltUp = new VirtualButton(this);
            VBTiltUp.Anchor = AnchorStyles.Top;
            VBTiltUp.Bounds = new Rectangle((this.Width - 20) / 2 + 1, 20 + 1, 18, 18);
            VBTiltUp.Text = "上";
            VBTiltUp.CheckedEnabled = true;
            VBTiltUp.CheckedBinding = GetUpChecked;
            VBTiltUp.ParentMinSize = new Size(60, 100);
            VBTiltUp.ParentMouseLeaveHide = true;
            VBTiltUp.ParentMouseLeaveCheckedShow = true;
            VBTiltUp.EnabledBinding = GetPTZEnabled;
            VBTiltUp.MouseDown += new EventHandler<MouseEventArgs>(VBTiltUp_MouseDown);
            VBTiltUp.MouseUp += new EventHandler<MouseEventArgs>(VBPTZStop_MouseUp);

            VBTiltDown = new VirtualButton(this);
            VBTiltDown.Anchor = AnchorStyles.Bottom;
            VBTiltDown.Bounds = new Rectangle((this.Width - 20) / 2 + 1, this.Height - 40 + 1, 18, 18);
            VBTiltDown.Text = "下";
            VBTiltDown.CheckedEnabled = true;
            VBTiltDown.CheckedBinding = GetDownChecked;
            VBTiltDown.ParentMinSize = new Size(60, 100);
            VBTiltDown.ParentMouseLeaveHide = true;
            VBTiltDown.ParentMouseLeaveCheckedShow = true;
            VBTiltDown.EnabledBinding = GetPTZEnabled;
            VBTiltDown.MouseDown += new EventHandler<MouseEventArgs>(VBTiltDown_MouseDown);
            VBTiltDown.MouseUp += new EventHandler<MouseEventArgs>(VBPTZStop_MouseUp);

            VBPanLeft = new VirtualButton(this);
            VBPanLeft.Anchor = AnchorStyles.Left;
            VBPanLeft.Bounds = new Rectangle(1, (this.Height - 20) / 2 + 1, 18, 18);
            VBPanLeft.Text = "左";
            VBPanLeft.CheckedEnabled = true;
            VBPanLeft.CheckedBinding = GetLeftChecked;
            VBPanLeft.ParentMinSize = new Size(60, 100);
            VBPanLeft.ParentMouseLeaveHide = true;
            VBPanLeft.ParentMouseLeaveCheckedShow = true;
            VBPanLeft.EnabledBinding = GetPTZEnabled;
            VBPanLeft.MouseDown += new EventHandler<MouseEventArgs>(VBPanLeft_MouseDown);
            VBPanLeft.MouseUp += new EventHandler<MouseEventArgs>(VBPTZStop_MouseUp);

            VBPanRight = new VirtualButton(this);
            VBPanRight.Anchor = AnchorStyles.Right;
            VBPanRight.Bounds = new Rectangle(this.Width - 20 - 1, (this.Height - 20) / 2 + 1, 18, 18);
            VBPanRight.Text = "右";
            VBPanRight.CheckedEnabled = true;
            VBPanRight.CheckedBinding = GetRightChecked;
            VBPanRight.ParentMinSize = new Size(60, 100);
            VBPanRight.ParentMouseLeaveHide = true;
            VBPanRight.ParentMouseLeaveCheckedShow = true;
            VBPanRight.EnabledBinding = GetPTZEnabled;
            VBPanRight.MouseDown += new EventHandler<MouseEventArgs>(VBPanRight_MouseDown);
            VBPanRight.MouseUp += new EventHandler<MouseEventArgs>(VBPTZStop_MouseUp);

            VBZoomTele = new VirtualButton(this);
            VBZoomTele.Bounds = new Rectangle(1, 20 + 1, 18, 18);
            VBZoomTele.Text = "高";
            VBZoomTele.CheckedEnabled = true;
            VBZoomTele.CheckedBinding = GetTeleChecked;
            VBZoomTele.ParentMinSize = new Size(60, 100);
            VBZoomTele.ParentMouseLeaveHide = true;
            VBZoomTele.ParentMouseLeaveCheckedShow = true;
            VBZoomTele.EnabledBinding = GetPTZEnabled;
            VBZoomTele.MouseDown += new EventHandler<MouseEventArgs>(VBZoomTele_MouseDown);
            VBZoomTele.MouseUp += new EventHandler<MouseEventArgs>(VBPTZStop_MouseUp);

            VBZoomWide = new VirtualButton(this);
            VBZoomWide.Anchor = AnchorStyles.Right | AnchorStyles.Top;
            VBZoomWide.Bounds = new Rectangle(this.Width - 20 - 1, 20 + 1, 18, 18);
            VBZoomWide.Text = "低";
            VBZoomWide.CheckedEnabled = true;
            VBZoomWide.CheckedBinding = GetWideChecked;
            VBZoomWide.ParentMinSize = new Size(60, 100);
            VBZoomWide.ParentMouseLeaveHide = true;
            VBZoomWide.ParentMouseLeaveCheckedShow = true;
            VBZoomWide.EnabledBinding = GetPTZEnabled;
            VBZoomWide.MouseDown += new EventHandler<MouseEventArgs>(VBZoomWide_MouseDown);
            VBZoomWide.MouseUp += new EventHandler<MouseEventArgs>(VBPTZStop_MouseUp);

            VBSpeedFast = new VirtualButton(this);
            VBSpeedFast.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
            VBSpeedFast.Bounds = new Rectangle(1, this.Height - 40, 18, 18);
            VBSpeedFast.Text = "快";
            VBSpeedFast.ParentMinSize = new Size(60, 100);
            VBSpeedFast.ParentMouseLeaveHide = true;
            VBSpeedFast.ParentMouseLeaveCheckedShow = true;
            VBSpeedFast.EnabledBinding = GetPTZEnabled;
            VBSpeedFast.MouseDown += new EventHandler<MouseEventArgs>(VBSpeedFast_MouseDown);

            VBSpeedSlow = new VirtualButton(this);
            VBSpeedSlow.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
            VBSpeedSlow.Bounds = new Rectangle(this.Width - 20 - 1, this.Height - 40, 18, 18);
            VBSpeedSlow.Text = "慢";
            VBSpeedSlow.ParentMinSize = new Size(60, 100);
            VBSpeedSlow.ParentMouseLeaveHide = true;
            VBSpeedSlow.ParentMouseLeaveCheckedShow = true;
            VBSpeedSlow.EnabledBinding = GetPTZEnabled;
            VBSpeedSlow.MouseDown += new EventHandler<MouseEventArgs>(VBSpeedSlow_MouseDown);

            VBAlarmYes = new VirtualButton(this);
            VBAlarmYes.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
            VBAlarmYes.Text = "是";
            VBAlarmYes.Bounds = new Rectangle(this.Width - 40 - 1, this.Height - 20, 18, 18);
            VBAlarmYes.CheckedEnabled = true;
            VBAlarmYes.CheckedBinding = GetYesChecked;
            VBAlarmYes.VisibleBinding = GetYesNoVisible;
            VBAlarmYes.ParentMinSize = new Size(100, 100);
            VBAlarmYes.MouseClick += new EventHandler<MouseEventArgs>(VBAlarmYes_MouseClick);

            VBAlarmNo = new VirtualButton(this);
            VBAlarmNo.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
            VBAlarmNo.Text = "否";
            VBAlarmNo.Bounds = new Rectangle(this.Width - 20 - 1, this.Height - 20, 18, 18);
            VBAlarmNo.CheckedEnabled = true;
            VBAlarmNo.CheckedBinding = GetNoChecked;
            VBAlarmNo.VisibleBinding = GetYesNoVisible;
            VBAlarmNo.ParentMinSize = new Size(100, 100);
            VBAlarmNo.MouseClick += new EventHandler<MouseEventArgs>(VBAlarmNo_MouseClick);

            VBPlayer = new VirtualButton(this);
            VBPlayer.Anchor = AnchorStyles.Right | AnchorStyles.Top;
            VBPlayer.Text = "播放器";
            VBPlayer.Bounds = new Rectangle(this.Width - 20 - 1, 40, 18, 48);
            VBPlayer.ParentMouseLeaveHide = true;
            VBPlayer.ParentMinSize = new Size(20, 200);
            VBPlayer.MouseClick += new EventHandler<MouseEventArgs>(VBPlayer_MouseClick);

            VBTitle = new VirtualButton(this);
            VBTitle.Bounds = new Rectangle(1, 1, 0, 0);
            VBTitle.ParentMouseLeaveHide = true;
            VBTitle.AutoSize = true;
            VBTitle.TextBinding = GetTitleText;
            VBTitle.Enabled = false;

            VBState = new VirtualButton(this);
            VBState.Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
            VBState.Bounds = new Rectangle(1, this.Height - 20, 0, 0);
            VBState.CheckedEnabled = true;
            VBState.CheckedBinding = GetStateChecked;
            VBState.AutoSize = true;
            VBState.TextBinding = GetStateText;
            VBState.ParentMouseLeaveHide = true;
            VBState.ParentMouseLeaveCheckedShow = true;
            VBState.Enabled = false;
        }

        void VBPlayer_MouseClick(object sender, MouseEventArgs e)
        {
            if (!this.Controls.Contains(this.userPlayer)) this.Controls.Add(this.userPlayer);
            this.userPlayer.Show();
        }

        bool GetCruiseChecked()
        {
            return (this.State & StateType.Cruise) == StateType.Cruise;
        }

        bool GetAnalyzeChecked()
        {
            return (this.State & StateType.Analyze) == StateType.Analyze;
        }

        bool GetRecordChecked()
        {
            return (this.State & StateType.Record) == StateType.Record;
        }

        bool GetUpChecked()
        {
            return (this.State & StateType.Up) == StateType.Up;
        }

        bool GetDownChecked()
        {
            return (this.State & StateType.Down) == StateType.Down;
        }

        bool GetLeftChecked()
        {
            return (this.State & StateType.Left) == StateType.Left;
        }

        bool GetRightChecked()
        {
            return (this.State & StateType.Right) == StateType.Right;
        }

        bool GetStateChecked()
        {
            return (this.State & StateType.Up) == StateType.Up
                || (this.State & StateType.Down) == StateType.Down
                || (this.State & StateType.Left) == StateType.Left
                || (this.State & StateType.Right) == StateType.Right;
        }

        bool GetTeleChecked()
        {
            return (this.State & StateType.Tele) == StateType.Tele;
        }

        bool GetWideChecked()
        {
            return (this.State & StateType.Wide) == StateType.Wide;
        }

        bool GetPTZEnabled()
        {
            return !((this.State & StateType.Cruise) == StateType.Cruise
                || (this.State & StateType.Analyze) == StateType.Analyze);
        }

        bool GetYesNoVisible()
        {
            return this.group != null && this.group.AlarmCount > 0 && this.group.AlarmCount > this.alarmCount;
        }

        bool GetYesChecked()
        {
            return this.group.GroupOperate == GroupOperate.Yes;
        }

        bool GetNoChecked()
        {
            return this.group.GroupOperate == GroupOperate.No;
        }

        string GetTitleText()
        {
            return string.Format("{0}-{1}", this.areaName, this.deviceName);
        }

        string GetStateText()
        {
            return string.Format("H:{0,-3} V:{1,-3} S:{2}", this.calculateHorizon, this.calculateVertical, this.panTiltSpeed);
        }

        VirtualButton VBVideoCruise;
        VirtualButton VBVideoAnalyze;
        VirtualButton VBVideoRecord;
        VirtualButton VBVideoSnap;
        VirtualButton VBTiltUp;
        VirtualButton VBTiltDown;
        VirtualButton VBPanLeft;
        VirtualButton VBPanRight;
        VirtualButton VBZoomTele;
        VirtualButton VBZoomWide;
        VirtualButton VBSpeedFast;
        VirtualButton VBSpeedSlow;
        VirtualButton VBClose;
        VirtualButton VBTitle;
        VirtualButton VBState;
        VirtualButton VBAlarmYes;
        VirtualButton VBAlarmNo;
        VirtualButton VBPlayer;

        #endregion

        #region 云镜控制
        void VBSpeedFast_MouseDown(object sender, MouseEventArgs e)
        {
            if (++this.panTiltSpeed == 8) this.panTiltSpeed = 1;
        }

        void VBSpeedSlow_MouseDown(object sender, MouseEventArgs e)
        {
            if (--this.panTiltSpeed == 0) this.panTiltSpeed = 7;
        }

        void VBZoomWide_MouseDown(object sender, MouseEventArgs e)
        {
            this.ZoomWide();
        }

        void VBZoomTele_MouseDown(object sender, MouseEventArgs e)
        {
            this.ZoomTele();
        }

        void VBPTZStop_MouseUp(object sender, MouseEventArgs e)
        {
            this.PTZStop();
        }

        void VBPanRight_MouseDown(object sender, MouseEventArgs e)
        {
            this.PanRight(this.panTiltSpeed);
        }

        void VBPanLeft_MouseDown(object sender, MouseEventArgs e)
        {
            this.PanLeft(this.panTiltSpeed);
        }

        void VBTiltDown_MouseDown(object sender, MouseEventArgs e)
        {
            this.TiltDown(this.panTiltSpeed);
        }

        void VBTiltUp_MouseDown(object sender, MouseEventArgs e)
        {
            this.TiltUp(this.panTiltSpeed);
        }
        #endregion

        #region 视频管理

        void VBVideoCruise_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.IsCruising) this.StopCruise();
            else this.StartCruise();
        }

        void VBVideoAnalyze_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.IsAnalyzing) this.StopAnalyze();
            else this.StartAnalyze();
        }

        void VBVideoRecord_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.IsRecording) this.StopRecord();
            else this.StartRecord();
        }

        void VBVideoSnap_MouseClick(object sender, MouseEventArgs e)
        {
            this.SnapVideo();
        }

        void VBClose_MouseClick(object sender, MouseEventArgs e)
        {
            this.CloseVideo();
        }

        #endregion

        #region 报警确认
        int alarmCount = 0; //确认报警时的报警数量
        void VBAlarmNo_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.group != null && this.group.AlarmCount > 0)
            {
                this.group.GroupOperate = GroupOperate.No;
                this.alarmCount = this.group.AlarmCount;
            }
        }

        void VBAlarmYes_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.group != null && this.group.AlarmCount > 0)
            {
                this.group.GroupOperate = GroupOperate.Yes;
                this.alarmCount = this.group.AlarmCount;
            }
        }
        #endregion

        #region 批量管理
        public event EventHandler SelectedChanged;
        protected virtual void OnSelectedChanged()
        {
            if (SelectedChanged != null) SelectedChanged(this, null);
        }

        static Dictionary<string, Dictionary<string, UserVideo>> videos = new Dictionary<string, Dictionary<string, UserVideo>>();

        bool isSelected = false;
        public bool IsSelected
        {
            get { return this.isSelected; }
            set
            {
                if (this.isSelected != value)
                {
                    this.isSelected = value;
                    OnSelectedChanged();
                }
            }
        }

        static public List<UserVideo> GetStateVideos(StateType state)
        {
            List<UserVideo> LUV = new List<UserVideo>();
            foreach (var area in videos.Values)
            {
                foreach (UserVideo video in area.Values)
                {
                    if ((video.State & state) == state) LUV.Add(video);
                }
            }

            return LUV;
        }

        static public void SelectAll(bool state)
        {
            foreach (var area in videos)
            {
                foreach (var device in area.Value)
                {
                    device.Value.IsSelected = state;
                }
            }
        }

        static public void SelectArea(string areaName, bool multiple)
        {
            if (videos.ContainsKey(areaName))
            {
                foreach (var area in videos)
                {
                    if (area.Key == areaName)
                        foreach (var device in area.Value) device.Value.IsSelected = true;
                    else if (!multiple)
                        foreach (var device in area.Value) device.Value.IsSelected = false;
                }
            }
        }

        static public void SelectDevice(string areaName, string deviceName, bool multiple)
        {
            if (videos.ContainsKey(areaName) && videos[areaName].ContainsKey(deviceName))
            {
                foreach (var area in videos)
                {
                    foreach (var device in area.Value)
                    {
                        if (area.Key == areaName && device.Key == deviceName)
                            device.Value.IsSelected = true;
                        else if (!multiple)
                            device.Value.IsSelected = false;
                    }
                }
            }
        }

        static public void LoginEncoders()
        {
            Fuction(StateType.Encoder, true);
        }

        static public void LogoutEncoders()
        {
            Fuction(StateType.Encoder, false);
        }

        static public void OpenVideos()
        {
            Fuction(StateType.Video, true);
        }

        static public void CloseVideos()
        {
            Fuction(StateType.Video, false);
        }

        static public void StartRecords()
        {
            Fuction(StateType.Record, true);
        }

        static public void StopRecords()
        {
            Fuction(StateType.Record, false);
        }

        static public void StartAnalyzes()
        {
            Fuction(StateType.Analyze, true);
        }

        static public void StopAnalyzes()
        {
            Fuction(StateType.Analyze, false);
        }

        static public void StartCruises()
        {
            Fuction(StateType.Cruise, true);
        }

        static public void StopCruises()
        {
            Fuction(StateType.Cruise, false);
        }

        static public void Snap()
        {
            Fuction(StateType.Snap, true);
        }

        static public void Up(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Up, true);
        }

        static public void Down(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Down, true);
        }

        static public void Left(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Left, true);
        }

        static public void Right(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Right, true);
        }

        static public void LeftUp(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Left | StateType.Up, true);
        }

        static public void LeftDown(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Left | StateType.Down, true);
        }

        static public void RightUp(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Right | StateType.Up, true);
        }

        static public void RightDown(byte speed)
        {
            UserVideo.speed = speed;
            Fuction(StateType.Right | StateType.Down, true);
        }

        static public void Wide()
        {
            Fuction(StateType.Wide, true);
        }

        static public void Tele()
        {
            Fuction(StateType.Tele, true);
        }

        static public void Open()
        {
            Fuction(StateType.Open, true);
        }

        static public void Close()
        {
            Fuction(StateType.Close, true);
        }

        static public void Near()
        {
            Fuction(StateType.Near, true);
        }

        static public void Far()
        {
            Fuction(StateType.Far, true);
        }

        static public void Stop()
        {
            Fuction(StateType.Stop, false);
        }

        static byte speed = 4;

        static void Fuction(StateType func, bool state)
        {
            foreach (var area in videos.Values)
            {
                foreach (UserVideo video in area.Values)
                {
                    if (!video.isSelected) continue;
                    switch (func)
                    {
                        case StateType.Encoder:
                            if (state) video.LoginEncoder();
                            else if (video.IsLogined) video.LogoutEncoder();
                            break;
                        case StateType.Video:
                            if (state && (video.IsLogined || video.LoginEncoder())) video.OpenVideo();
                            if (!state && video.IsOpened) video.CloseVideo();
                            break;
                        case StateType.Record:
                            if (state && (video.IsLogined || video.LoginEncoder())
                                && video.IsOpened || video.OpenVideo()) video.StartRecord();
                            if (!state && video.IsRecording) video.StopRecord();
                            break;
                        case StateType.Analyze:
                            if (state && (video.IsLogined || video.LoginEncoder())
                                && video.IsOpened || video.OpenVideo()) video.StartAnalyze();
                            if (!state && video.IsAnalyzing) video.StopAnalyze();
                            break;
                        case StateType.Cruise:
                            if (state && (video.IsLogined || video.LoginEncoder())
                                && video.IsOpened || video.OpenVideo()) video.StartCruise();
                            if (!state && video.IsCruising) video.StopCruise();
                            break;
                        case StateType.Snap:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.SnapVideo();
                            break;
                        case StateType.Up:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.TiltUp(speed);
                            break;
                        case StateType.Down:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.TiltDown(speed);
                            break;
                        case StateType.Left:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.PanLeft(speed);
                            break;
                        case StateType.Right:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.PanRight(speed);
                            break;
                        case StateType.Left | StateType.Up:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.PanLeftTiltUp(speed);
                            break;
                        case StateType.Left | StateType.Down:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.PanLeftTiltDown(speed);
                            break;
                        case StateType.Right | StateType.Up:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.PanRightTiltUp(speed);
                            break;
                        case StateType.Right | StateType.Down:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.PanRightTiltDown(speed);
                            break;
                        case StateType.Wide:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.ZoomWide();
                            break;
                        case StateType.Tele:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.ZoomTele();
                            break;
                        case StateType.Open:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.IrisOpen();
                            break;
                        case StateType.Close:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.IrisClose();
                            break;
                        case StateType.Near:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.FocusNear();
                            break;
                        case StateType.Far:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.FocusFar();
                            break;
                        case StateType.Stop:
                            if (video.IsOpened && !video.IsCruising && !video.IsAnalyzing) video.PTZStop();
                            break;
                        case StateType.Other:
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        #endregion

        #region 解码显示
        Control decodeShow = null;
        /// <summary>
        /// 解码显示控件
        /// </summary>
        [Browsable(false)]
        public Control DecodeShow { get; set; }

        //protected override void OnVideoDecode(IntPtr buffer, int width, int height)
        //{
        //    base.OnVideoDecode(buffer, width, height);

        //    if (this.decodeShow != null)
        //    {
        //        Bitmap decodeImage = new Bitmap(width, height);

        //        ImageProcessing.YV12.DecodeYV12ToRGB(buffer, decodeImage);
        //        //ImageProcessing.YV12.DecodeYV12ToGrey(buffer, decodeImage);
        //        this.decodeShow.CreateGraphics().DrawImage(decodeImage, 0, 0, this.decodeShow.Width, this.decodeShow.Height);
        //        decodeImage.Dispose();
        //    }
        //}

        public Control AnalyzeShow;
        protected override void OnAnalyzeAlarm(AlarmEventArgs e, Bitmap frame)
        {
            if (this.AnalyzeShow != null && !this.AnalyzeShow.IsDisposed)
            {
                this.AnalyzeShow.CreateGraphics().DrawImage(frame, 0, 0, this.AnalyzeShow.ClientSize.Width, this.AnalyzeShow.ClientSize.Height);
            }

            base.OnAnalyzeAlarm(e, frame);
        }
        #endregion

        #region 视频绘图
        int alarmIndex = 0;//报警索引
        Stopwatch swAlarm = Stopwatch.StartNew();
        protected override void OnVideoPaint(VideoPaintEventArgs e)
        {
            Graphics G = e.Graphics;

            #region 绘制虚拟按钮
            VirtualButton.VirtualPaint(this, G);
            #endregion

            #region 绘制选择框
            if (this.isSelected)
            {
                Rectangle rectSelected = new Rectangle(0, 0, this.Width - 3, this.Height - 2);
                VirtualBase.DrawRectangle(G, Pens.Lime, rectSelected);
            }
            #endregion

            #region 绘制报警框
            if (this.group == null && this.alarmCount != 0) this.alarmCount = 0;
            if (this.group != null && this.group.AlarmCount > 0 && this.group.AlarmCount > this.alarmCount)
            {
                if (swAlarm.ElapsedMilliseconds < 500)
                {
                    alarmIndex %= this.group.AlarmCount;
                    AlarmInfo alarm = this.group[alarmIndex];
                    float w = (float)this.Width / (float)this.VideoWidth;
                    float h = (float)this.Height / (float)this.VideoHeight;
                    for (int i = 0; i < alarm.AlarmRegion.Length; i++)
                    {
                        RectangleF rectAlarm = new RectangleF(
                            alarm.AlarmRegion[i].X * w,
                            alarm.AlarmRegion[i].Y * h,
                            alarm.AlarmRegion[i].Width * w,
                            alarm.AlarmRegion[i].Height * h);
                        Color colorAlarm = Color.FromArgb(
                            ((AlarmRegionEnum)alarm.AlarmRegionType[i] & AlarmRegionEnum.Fire) == AlarmRegionEnum.Fire ? 255 : 0,
                            ((AlarmRegionEnum)alarm.AlarmRegionType[i] & AlarmRegionEnum.Smoke) == AlarmRegionEnum.Smoke ? 255 : 0,
                            ((AlarmRegionEnum)alarm.AlarmRegionType[i] & AlarmRegionEnum.Motion) == AlarmRegionEnum.Motion ? 255 : 0);

                        using (Pen pen = new Pen(colorAlarm))
                        {
                            VirtualBase.DrawRectangle(G, pen, Rectangle.Round(rectAlarm));
                        }

                    }
                    Pen penAlarm = new Pen(Color.Red, 3f);
                    VirtualBase.DrawRectangle(G, penAlarm, new Rectangle(2, 2, this.Width - 7, this.Height - 6));
                    penAlarm.Dispose();
                }
                else if (swAlarm.ElapsedMilliseconds > 1000)
                {
                    alarmIndex++;
                    swAlarm.Reset();
                    swAlarm.Start();
                }
            }
            else if (alarmIndex != 0) alarmIndex = 0;
            #endregion

            base.OnVideoPaint(e);

        }

        protected override void OnVideoClosed()
        {
            base.OnVideoClosed();

            this.isSelected = false;
            if (SelectedChanged != null) SelectedChanged(this, null);
        }
        #endregion

        #region 鼠标键盘
        static bool isControlDown = false;
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.Control)
                isControlDown = true;
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);
            if (!e.Control)
                isControlDown = false;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (isControlDown && this.isSelected) this.isSelected = false;
            else SelectDevice(this.areaName, this.deviceName, isControlDown);

            base.OnMouseDown(e);
        }
        #endregion
    }
}
